﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Reflection;
using Microsoft.Win32;
using System.IO;
using System.Net.NetworkInformation;
using RookieLibSharp.Database;
using BirthdayRemainder.Model;
using RookieLibSharp.Configuration;
using System.Diagnostics;
using RookieLibSharp.Calendar;
using NPOI.HSSF.UserModel;
using NPOI.HPSF;
using NPOI.POIFS.FileSystem;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.XSSF;

using System.Runtime.InteropServices;

namespace BirthdayRemainder
{
    public static class Funcs
    {
        /// <summary>
        /// 全局变量初始化
        /// </summary>
        public static void InitPubVal()
        {
            //PubVal.SftwareDataDir = string.Format(@"{0}\AppData\Roaming\{1}\", Environment.GetFolderPath(Environment.SpecialFolder.Personal), PubVal.SFTWARE_NAME);
            GlobalValue.SftwareDataDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\" + GlobalValue.SFTWARE_NAME + "\\";
            CreateDir(GlobalValue.SftwareDataDir);
            Cfg.Initialize(ConfigFileType.INI, GlobalValue.SftwareDataDir + "cfg.bin");
            Cfg.SetCfgPath(GlobalValue.SftwareDataDir + GlobalValue.SFT_CFG_FILE_NAME);
        }
        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="dir"></param>
        public static void CreateDir(string dir)
        {
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
        }
        /// <summary>
        /// 判断字符串是否为全数字
        /// </summary>
        /// <param name="_str"></param>
        /// <returns></returns>
        public static bool IsNum(string _str)
        {
            if ((_str == null) ||(_str.Length == 0))
            {
                return false;
            }
            return Regex.IsMatch(_str, @"^\d+$");
        }
        /// <summary>
        /// 判断字符串是否为手机号码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsPhoneNum(string str)
        {
            return Regex.IsMatch(str,@"^((\d3 )|(\d{3}\-))?13[0-9]\d{8}|15[89]\d{8}");
        }
        /// <summary>
        /// 判断字符串是否为小数
        /// </summary>
        /// <param name="_str"></param>
        /// <returns></returns>
        public static bool IsDbl(string _str)
        {
            if (IsNum(_str))
            {
                return true;
            }
            else
            {
                return Regex.IsMatch(_str, @"^\d+\.\d+$");
            }
        }
        /// <summary>
        /// 获取当前版本号
        /// </summary>
        /// <returns></returns>
        public static Version GetSftVersion()
        {
            Assembly AppAssembly = Assembly.GetExecutingAssembly();
            return AppAssembly.GetName().Version;
        }
        /// <summary>
        /// 设置开机启动
        /// </summary>
        /// <param name="started">是否开机启动</param>
        /// <param name="path">需要启动的程序路径</param>
        /// <returns>设置成功与否</returns>
        public static bool runWhenStart(bool started,string path)
        {
            const string reg_path = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
            const string exeName = "BirthdayRemainder";
            RegistryKey key = Registry.LocalMachine.OpenSubKey(reg_path, true);//打开注册表子项 
            if (key == null)//如果该项不存在的话，则创建该子项 
            {
                key = Registry.LocalMachine.CreateSubKey(reg_path);
            }
            if (started == true)
            {
                try
                {
                    key.SetValue(exeName, path);//设置为开机启动 
                    key.Close();
                }
                catch
                {
                    return false;
                }
            }
            else
            {
                try
                {
                    key.DeleteValue(exeName);//取消开机启动 
                    key.Close();
                }
                catch
                {
                    return false;
                }
            }
            return true;
        }
        /// <summary>
        /// 判断是否为日期
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsDate(string str)
        {
            try
            {
                Convert.ToDateTime(str);
                return true;
            }
            catch
            {
                return false;
            }
        }
        /// <summary>
        /// 获取阴历日历
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string GetLunarStr(DateTime dateTime)
        {
            string str = "今天是：" + dateTime.ToString("yyyy-MM-dd ");
            ChineseCalendar CalInfo = new ChineseCalendar(dateTime);
            str += string.Format("农历 {0}年{1}月{2}",CalInfo.LunarYearText , CalInfo.LunarMonthText , CalInfo.LunarDayText);
            return str;
        }
        /// <summary>
        /// 判断网络是否连接成功
        /// </summary>
        /// <returns></returns>
        public static bool CheckNetConnection()
        {
            return NetworkInterface.GetIsNetworkAvailable();
        }
        /// <summary>
        /// CheckMailAddr()
        /// 检查邮件地址是否合法
        /// </summary>
        /// <param name="_MailAddr"></param>
        /// <returns></returns>
        public static bool CheckMailAddr(string _MailAddr)
        {
            return Regex.IsMatch(_MailAddr, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        /// <summary>
        /// 返回本机安装的Excel版本
        /// </summary>
        /// <returns></returns>
        public static ExcelVersion GetExcelVersion()
        {
            string path = "";
            Microsoft.Win32.RegistryKey regKey = null;
            Microsoft.Win32.RegistryKey regSubKey = null;
            regKey = Microsoft.Win32.Registry.LocalMachine;
            //获取exe键值
            regSubKey = regKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe", false);
            if (regSubKey != null)
            {
                //获取路径
                path = regSubKey.GetValue("Path").ToString();
                //判断exe文件是否存在
                if (File.Exists(path + "Excel.exe"))
                {
                    //判断版本信息，获取版本号数字
                    Match m = Regex.Match(path, @"(?<=Office)\d+");
                    if (m != null)
                    {
                        //返回对应exe版本号
                        return GetExcelVersion(Convert.ToInt32(m.Value));
                    }
                }
            }
            //没有找到，返回null
            return ExcelVersion.ExcelNull;
        }

        /// <summary>
        /// 根据版本编号返回版本号
        /// </summary>
        /// <param name="verIdx">版本编号</param>
        /// <returns></returns>
        private static ExcelVersion GetExcelVersion(int verIdx)
        {
            switch (verIdx)
            {
                case 15:
                    return ExcelVersion.Excel2013;
                case 14:
                    return ExcelVersion.Excel2010;
            }
            return ExcelVersion.ExcelNull;
        }
        /// <summary>
        /// 判断文件是否被打开了
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static bool IsFileInUse(string filePath)
        {
            bool inUse = true;
            if (!File.Exists(filePath))
            {
                return false;
            }
            FileStream FS = null;
            try
            {
                FS = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
                inUse = false;
            }
            catch
            {

            }
            finally
            {
                if (FS != null)
                {
                    FS.Close();
                }
            }
            return inUse;
        }
        public static bool IsANewDay()
        {
            //获取保存的日期，和当天日期比较，如果是今天日期，则表示已经检测过升级了，当天不再检测升级
            string strDate = Cfg.ReadString(GlobalValue.SFT_CFG, GlobalValue.SFT_CFG_TODAY);
            if (0 == string.Compare(strDate, DateTime.Today.ToString(GlobalValue.STR_DATE_TIME_FORMAT)))
            {
                return false;
            }
            //如果不是当天日期，表示当天没有进行检测升级，需要检测升级，并写入当前日期
            Cfg.WriteConfig(GlobalValue.SFT_CFG, GlobalValue.SFT_CFG_TODAY, DateTime.Today.ToString(GlobalValue.STR_DATE_TIME_FORMAT));

            Cfg.WriteConfig(GlobalValue.SFT_CFG, GlobalValue.SFT_CFG_NOT_FRM_REMAIND, false);
            Cfg.WriteConfig(GlobalValue.SFT_CFG, GlobalValue.SFT_CFG_NOT_CHK_UPDATE, false);
            Cfg.WriteConfig(GlobalValue.SFT_CFG, GlobalValue.SFT_CFG_NOT_MAIL_REMIND, false);
            return true;
        }
        public static string GetRemindStr()
        {
            int remaindDays = Cfg.ReadInt(GlobalValue.SFT_CFG, GlobalValue.SFT_CFG_REMAIND_DAYS);
            List<PersonInfo> LstInfo = SftMgr.DbGetAllInfo();
            string strRemind = "今天生日：\n\n";
            int cnt = 0;
            foreach (var info in LstInfo)
            {
                if (info.DayToBirthday == 0)
                {
                    strRemind += string.Format("  姓名：{0}\t年龄:{1}岁\n", info.Name, info.Age);
                    cnt++;
                }
            }
            if (cnt == 0)
            {
                strRemind = "";
            }
            string str = strRemind;
            strRemind = "\n近期生日：\n\n";
            cnt = 0;
            foreach (var info in LstInfo)
            {
                if ((info.DayToBirthday > 0) && (info.DayToBirthday <= remaindDays))
                {
                    strRemind += string.Format("  姓名：{0}\t年龄:{1}岁\t距离生日:{2}天\n", info.Name, info.Age, info.DayToBirthday);
                    cnt++;
                }
            }
            if (cnt == 0)
            {
                strRemind = str;
            }
            else
            {
                strRemind = str + strRemind;
            }
            return strRemind;
        }
        public static string GetMailSendServer(string mailAddr)
        {
            string str = Regex.Match(mailAddr, @"(?<=@).+$").Value;

            return string.Format("smtp.{0}", str);
        }
        public static bool AppIsRunning(string ProcName)
        {
            Process[] Proc = Process.GetProcesses();
            ProcName = ProcName.ToLower();
            foreach (System.Diagnostics.Process pro in Proc)
            {
                if (pro.ProcessName.ToLower().IndexOf(ProcName) != -1)
                {
                    return true;
                }
            }
            return false;
        }
        public static bool KillApp(string ProcName)
        {
            Process[] Proc = Process.GetProcesses();
            ProcName = ProcName.ToLower();
            foreach (System.Diagnostics.Process pro in Proc)
            {
                if (pro.ProcessName.ToLower().IndexOf(ProcName) != -1)
                {
                    try
                    {
                        pro.Kill();
                        return true;
                    }
                    catch
                    {
                        return false;
                    }
                }
            }
            return false;
        }
        public static bool RunApp(string appPath, string args = null)
        {
            if (!File.Exists(appPath))
            {
                return false;
            }
            if (AppIsRunning(Path.GetFileNameWithoutExtension(appPath)))
            {
                return false;
            }
            try
            {
                if (args == null)
                {
                    Process.Start(appPath);
                }
                else
                {
                    Process.Start(appPath, args);
                }
                return true;
            }
            catch
            {
            }
            return false;
        }

        public static string[] GetSheetNamesFromWorkbook(string filePath)
        {
            IWorkbook wkBk;
            FileStream FS = new FileStream(filePath, FileMode.Open, FileAccess.Read);
            if (Path.GetExtension(filePath) == ".xls")
            {
                wkBk = new HSSFWorkbook(FS);
            }
            else
            {
                wkBk = new XSSFWorkbook(FS);
            }
            string[] ArrName = new string[wkBk.NumberOfSheets];
            ISheet wkSht;
            for (int idx = 0; idx < wkBk.NumberOfSheets;idx++ )
            {
                wkSht = wkBk.GetSheetAt(idx);
                ArrName[idx] = wkSht.SheetName;
            }
            FS.Close();
            return ArrName;
        }
        public static bool IsRegSucess()
        {
            return Cfg.ReadBool(GlobalValue.SFT_CFG, GlobalValue.SFT_CFG_REGISTER, false);
        }
        public static bool DateTimeIsValid(int year, int month, int day)
        {
            if (year < 1970 || month < 1 || month > 12 || day <1||day>31)
            {
                return false;
            }
            //2月闰年29天，非闰年28天
            //1、3、5、7、8、10、12每月31天
            //4、6、9、11每月30天
            switch(month)
            {
                case 2:
                    //如果是闰年
                    if (DateTime.IsLeapYear(year))
                    {
                        if (day>29)
                        {
                            return false;
                        }
                    }
                    else
                    {
                        if (day>28)
                        {
                            return false;
                        }
                    }
                    break;
                case 1:
                case 3:
                case 5:
                case 7:
                case 8:
                case 10:
                case 12:
                    break;
                default://4,6,9,11
                    if (day > 30)
                    {
                        return false;
                    }
                    break;
            }
            return true;
        }
    }
}
